package com.yxsk.relay.job.component.admin.facade.restful;

import com.yxsk.relay.job.component.admin.exception.registry.RelayJobRegistryException;
import com.yxsk.relay.job.component.admin.facade.Guard;
import com.yxsk.relay.job.component.admin.registry.Steward;
import com.yxsk.relay.job.component.admin.utils.HttpContextUtils;
import com.yxsk.relay.job.component.common.constant.NetProtocol;
import com.yxsk.relay.job.component.common.constant.UriConstant;
import com.yxsk.relay.job.component.common.protocol.message.base.ResultResponse;
import com.yxsk.relay.job.component.common.protocol.message.renewal.RenewalRequest;
import com.yxsk.relay.job.component.common.protocol.message.renewal.RenewalResponse;
import com.yxsk.relay.job.component.common.protocol.message.termination.TerminationRequest;
import com.yxsk.relay.job.component.common.protocol.message.termination.TerminationResponse;
import com.yxsk.relay.job.component.common.utils.DateUtils;
import com.yxsk.relay.job.component.common.vo.Endpoint;
import com.yxsk.relay.job.component.common.vo.SlaveInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Date;

/**
 * @Author 11376
 * @CreaTime 2019/6/8 23:43
 * @Description
 */
@Slf4j
@Api(description = "Relay-Job工作端点注册服务")
@RestController
public class HttpRestfulGuard implements Guard {

    @Autowired
    private Steward steward;

    @ApiOperation("服务续期")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "serialNo", value = "流水号", required = true),
            @ApiImplicitParam(name = "version", value = "版本", required = true),
            @ApiImplicitParam(name = "requestTime", value = "请求时间", required = true),
            @ApiImplicitParam(name = "token", value = "token"),
            @ApiImplicitParam(name = "host", value = "主机", required = true),
            @ApiImplicitParam(name = "netProtocol", value = "业务通讯协议")
    })
    @Override
    @PostMapping(UriConstant.RENEWAL_URI)
    public ResultResponse renewal(@RequestBody @Valid RenewalRequest request) {
        NetProtocol netProtocol = StringUtils.hasLength(request.getNetProtocol()) ? NetProtocol.getProtocol(request.getNetProtocol()) : NetProtocol.HTTP;

        Endpoint endpoint = new Endpoint();
        endpoint.setHost(request.getHost());
        endpoint.setPort(request.getPort());
        endpoint.setAuthToken(request.getAuthToken());
        endpoint.setProtocol(netProtocol);

        SlaveInfo info = new SlaveInfo(request.getAppName(), endpoint, request.getResourceInfo());
        RenewalResponse response = new RenewalResponse();
        response.setRequestSerialNo(request.getSerialNo());
        Date expirationDate = null;
        try {
            expirationDate = this.steward.renewal(info, HttpContextUtils.getQuestHeader(UriConstant.AUTHORIZATION_HEADER_KEY));
            response.setExpirationDate(expirationDate);
            response.setRespTime(DateUtils.getCurrentDate());
        } catch (RelayJobRegistryException e) {
            log.error("Slave renewal error", e);
            response.setRespTime(DateUtils.getCurrentDate());
            return ResultResponse.fail("STEWARD-RENEWAL-ERROR-0001", e.getMessage(), response);
        }
        return ResultResponse.ok(response);
    }

    @ApiOperation("服务下线")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "serialNo", value = "流水号", required = true),
            @ApiImplicitParam(name = "version", value = "版本", required = true),
            @ApiImplicitParam(name = "requestTime", value = "请求时间", required = true),
            @ApiImplicitParam(name = "token", value = "token"),
            @ApiImplicitParam(name = "host", value = "主机", required = true),
            @ApiImplicitParam(name = "reason", value = "下线原因")
    })
    @PostMapping(UriConstant.TERMINATE_URI)
    @Override
    public ResultResponse terminate(@RequestBody @Valid TerminationRequest request) {
        if (log.isDebugEnabled()) {
            log.debug("Slave terminated, host[{}], reason[{}]", request.getHost(), request.getReason());
        }
        TerminationResponse response = new TerminationResponse();
        response.setRequestSerialNo(request.getSerialNo());

        Endpoint endpoint = new Endpoint();
        endpoint.setHost(request.getHost());

        SlaveInfo info = new SlaveInfo(request.getAppName(), endpoint, null);
        try {
            this.steward.terminate(info, HttpContextUtils.getQuestHeader(UriConstant.AUTHORIZATION_HEADER_KEY));
            response.setRespTime(DateUtils.getCurrentDate());
        } catch (RelayJobRegistryException e) {
            log.error("Slave terminate error", e);
            response.setRespTime(DateUtils.getCurrentDate());
            return ResultResponse.fail("STEWARD-TERMINATE-ERROR-0002", e.getMessage(), response);
        }
        return ResultResponse.ok(response);
    }

}
